package com.migrate.module.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONNull;
import com.migrate.module.config.ApplicationContextUtil;
import java.util.*;

/**
 * 数据迁移工具类
 *
 * @author zhonghuashishan
 */
public class MigrateUtil {
    /**
     * 第一个数据源Mapper后缀（数据迁移新表是用的第二个数据源，所以统一规则用实体类名+02Mapper作为mapper名称）：02Mapper
     */
    static String SUFFIX_01MAPPER = "01Mapper";
    /**
     * 第二个数据源Mapper后缀（数据迁移新表是用的第二个数据源，所以统一规则用实体类名+02Mapper作为mapper名称）：02Mapper
     */
    static String SUFFIX_02MAPPER = "02Mapper";
    /**
     * Service后缀：Service
     */
    static String SUFFIX_SERVICE = "Service";
    /**
     * 根据表名取得第一个数据源的Mapper
     * @param tableName 表名
     * @return mapper
     */
    public static Object getD1MapperByTableName (String tableName)
    {
        if (StrUtil.isNotBlank(tableName))
        {
            // 这里先将tableName的首字母转为小写再转为驼峰命名，原因是假设传过来的表名是类似Order这种首字母大写的只有一个单词的表名，hutool返回的仍然会是Order，按这个名字去spring里显然是取不到bean的
            String beanName = StrUtil.toCamelCase(StrUtil.lowerFirst(tableName));
            // 拼接后缀Mapper
            beanName = beanName + SUFFIX_01MAPPER;
            // 从Spring IOC容器获取mapper
            return ApplicationContextUtil.getBean(beanName);
        }
        return null;
    }
    /**
     * 根据表名取得第二个数据源的Mapper
     * @param tableName 表名
     * @return mapper
     */
    public static Object getD2MapperByTableName (String tableName)
    {
        if (StrUtil.isNotBlank(tableName))
        {
            // 这里先将tableName的首字母转为小写再转为驼峰命名，原因是假设传过来的表名是类似Order这种首字母大写的只有一个单词的表名，hutool返回的仍然会是Order，按这个名字去spring里显然是取不到bean的
            String beanName = StrUtil.toCamelCase(StrUtil.lowerFirst(tableName));
            // 拼接后缀Mapper
            beanName = beanName + SUFFIX_02MAPPER;
            // 从Spring IOC容器获取mapper
            return ApplicationContextUtil.getBean(beanName);
        }
        return null;
    }
    /**
     * 根据表名取得Service
     * @param tableName 表名
     * @return 对应的service
     */
    public static Object getServiceByTableName (String tableName)
    {
        if (StrUtil.isNotBlank(tableName))
        {
            // 这里先将tableName的首字母转为小写再转为驼峰命名，原因是假设传过来的表名是类似Order这种首字母大写的只有一个单词的表名，hutool返回的仍然会是Order，按这个名字去spring里显然是取不到bean的
            String beanName = StrUtil.toCamelCase(StrUtil.lowerFirst(tableName));
            // 拼接后缀Mapper
            beanName = beanName + SUFFIX_SERVICE;
            // 从Spring IOC容器获取service
            return ApplicationContextUtil.getBean(beanName);
        }
        return null;
    }

    /**
     * 将List<Map <String, String>>里的元素的key转为驼峰命名法返回
     * @param sourceList 源List
     * @return 转换后的List
     */
    public static List<Map <String, Object>> toCamelCaseMapList (List <Map<String, Object>> sourceList)
    {
        if (CollUtil.isNotEmpty(sourceList))
        {
            List<Map<String, Object>> targetList = new ArrayList<>(sourceList.size());
            // 将结果转换为驼峰命名
            for (Map<String, Object> sourceMap : sourceList)
            {
                Map<String, Object> targetMap = new HashMap<>(sourceMap.size());
                sourceMap.forEach((key, value) -> targetMap.put(StrUtil.toCamelCase(key), value));
                targetList.add(targetMap);
            }
            return targetList;
        }
        return new ArrayList<>();
    }


    /**
     * 对集合中存在的空value值进行移除
     * @param mapList
     * @return
     */
    public static List <Map <String, Object>> removeNullValue(List <Map <String, Object>> mapList){
        for (Map <String, Object> map:mapList){
            removeNullValue(map);
        }
        return mapList;
    }

    /**
     * 更正Map中的Value空值对象类型
     * @param map
     */
    public static Map updateNullValue(Map map) {
        Set set = map.keySet();
        Map updateMap = new HashMap();
        for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
            Object obj = (Object) iterator.next();
            Object value = (Object) map.get(obj);

            if (value.equals(JSONNull.NULL)){
                updateMap.put(obj, null);
            } else {
                updateMap.put(obj, value);
            }
        }
        return updateMap;
    }
    /**
     * 移除map中的value空值
     * @param map
     * @return
     */
    private static void removeNullValue(Map map) {
        Set set = map.keySet();
        for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
            Object obj = (Object) iterator.next();
            Object value = (Object) map.get(obj);
            remove(value, iterator);
        }
    }


    /**
     * @param obj
     * @param iterator
     */
    private static void remove(Object obj,Iterator iterator){
        if (obj.equals(JSONNull.NULL)){
            iterator.remove();
        }

    }
}
